local japi = require 'jass.japi'
local code = require 'jass.code'
local base64 = require "util.base64"

--[[
    地图未开通服务器存档，无法使用服务器存档功能。（错误码:1750）

    网络异常，卡顿导致数据读取出错；服务器存档初始化失败，请重进游戏试试（错误码:1751）
    请重进游戏试试，原因如上（错误码:1752）
    请重进游戏试试，原因如上（错误码:1753）
    请重进游戏试试，原因如上（错误码:1190）

    服务器存档KEY值超过64位，请联系作者（错误码:1191）
    服务器存档数量达到上限，存储失败（错误码：1192）
    该地图无法使用服务器存档（错误码：1193）
    服务器存档增加的值超出上限 (错误码：1250)

    装备掉落达到今日上限 (错误码：1254)
    装备数量到达上限 （错误码:1255）

    NEW:
    全局存档存的值 超过21位;全局存档不能存64位长度(错误码：1759)

    1755: 没有存档组
    1756: 上传时间还未开始
    1757: 超过上传频率
    1758: 超过每局最大值
    1760: 上传时间超过当前时间
    1761: 小于每局最大值
    1762: 该KEY不是全局存档KEY
    1763: 没有VALUE
    1941: 写入频率过快
]]

local export = {}

export.type = 'dz'

-- 获取模式配置
function export.get_match_type()
    return japi.DzAPI_Map_GetMatchType()
end 

function export.get_map_config(name)
    return japi.DzAPI_Map_GetMapConfig(name)
end

-- 获取游戏开始时间
function export.get_game_starttime()
    if not export.game_starttime then
        export.game_starttime = japi.DzAPI_Map_GetGameStartTime()
    end
    return export.game_starttime
end

local mt = ac.player.__index


-- 是否读取成功
function mt:is_succuse()
    if package.local_test then
        return true
    end
    return self.server_error_code == 0 and self.server_loaded_items == true
end

-- 获取公会名
function mt:get_guild_name()
    return self.server_guild_name or ""
end

-- 获取公会职务
function mt:get_guild_role()
    if self.server_guild_role == 30 then
        return "会长"
    elseif self.server_guild_role == 20 then
        return "管理员"
    end
    return "成员"
end

-- 获取游戏局数
function mt:get_game_count()
    return self.server_game_count or 1
end

-- 获取地图等级
function mt:get_map_level()
    return self.server_game_level or 1
end

-- 获取地图等级排行
function mt:get_map_level_rank()
    return japi.DzAPI_Map_GetMapLevelRank(self.handel) 
end 

-- 是地图作者
function mt:is_author()
    return self.server_author == true
end

-- 是会员
function mt:is_vip()
    return self.server_vip == true
end

-- 获取积分
function mt:get_score(name)
    if not self.rpg_scores[name] then
        if self:is_succuse() then
            self.rpg_scores[name] = tonumber(japi.DzAPI_Map_GetServerValue(self.handle, name))
            print(('获取RPG积分:[%s][%s] = [%s]'):format(self:get_name(), name, self.rpg_scores[name]))
        else
            self.rpg_scores[name] = 0
        end
    end
    return self.rpg_scores[name]
end

-- 保存积分
function mt:set_score(name, value)
    assert(math.type(value) == 'integer', "积分只能保存 “整数” ")
    self.rpg_scores[name] = value
    if self:is_succuse() then
        japi.DzAPI_Map_SaveServerValue(self.handle, name, tostring(value))
        print(('设置RPG积分:[%s][%s] = [%s]'):format(self:get_name(), name, value))
    end
end

-- 累加积分
function mt:add_score(name, value, is_pc)
    self:set_score(name, self:get_score(name) + value)
end

-- 设置房间显示
function mt:set_stat(name, value)
    if self:is_succuse() then
        japi.DzAPI_Map_Stat_SetStat(self.handle, name, tostring(value))
        print(('设置房间显示:[%s][%s] = [%s]'):format(self:get_name(), name, value))
    end
end

-- 保存存档
function mt:save_server(name, value)
    assert(type(value) == 'string', "存档只能保存 “字符串” ")
    assert(#(value) <= 64, "存档长度超过上限")
    if self.rpg_servers[name] == value then
        return
    end
    self.rpg_servers[name] = value
    if self:is_succuse() then
        print(('dz设置RPG存档:[%s][%s] = [%s]'):format(self:get_name(), name, value))
        japi.DzAPI_Map_SaveServerValue(self.handle, name, value)
    end
end

-- 获取网易真实名字
function mt:get_user_name()
    return self.user_name
end

-- 读取存档
function mt:load_server(name)
    if not self.rpg_servers[name] then
        if self:is_succuse() then
            self.rpg_servers[name] = japi.DzAPI_Map_GetServerValue(self.handle, name) or ""
        else
            self.rpg_servers[name] = ""
        end
    end
    return self.rpg_servers[name]
end

-- 获取玩家次数类道具剩余次数
function mt:get_item_count(name)
    if not self.rpg_items[name] then
        if self:is_succuse() then
            self.rpg_items[name] = japi.RequestExtraIntegerData(41, self.handle, name, nil, false, 0, 0, 0)
        else
            self.rpg_items[name] = 0
        end
    end
    return self.rpg_items[name]
end

-- 消耗次数性道具 TODO 未验证
function mt:use_item(name, amount)
    amount = amount or 1
    if self:get_item_count(name) >= amount then
        self.rpg_items[name] = self.rpg_items[name] - amount
        japi.RequestExtraBooleanData(42, self.handle, name, nil, false, amount, 0, 0)
    end
end

-- 玩家是否拥有状态(时间类 道具)
function mt:has_status(name)
    if not self.rpg_status[name] then
        if self:is_online() then
            self.rpg_status[name] = japi.DzAPI_Map_HasMallItem(self.handle, name) and 1 or 0
        else
            self.rpg_status[name] = 0
        end
    end
    return self.rpg_status[name] == 1
end

-- 玩家是否拥有道具(次数类 道具)
function mt:has_item(name)
    return self:get_item_count(name) > 0
end

function export.init()
    for i = 1, 12 do
        local p = ac.player(i)
        p.rpg_scores = {}
        p.rpg_servers = {}
        p.rpg_items = {}
        p.rpg_status = {}
        p.server_error_code = 0
        p.server_loaded_items = true
        p.server_author = false 
        p.server_vip = false
        p.server_game_count = 0
        p.user_name = p:get_default_name() 

        if not package.local_test then 
            local uuid = japi.RequestExtraStringData(81, p.handle, nil, nil, false, 0, 0, 0)
            if uuid and uuid ~= "" and uuid:find("#") then 
                p.user_name = uuid
            end 
            p.server_error_code = japi.DzAPI_Map_GetServerValueErrorCode(p.handle)
            p.server_loaded_items = japi.RequestExtraBooleanData(77, p.handle, nil, nil, false, 0, 0, 0)
            p.server_author = japi.RequestExtraBooleanData(50, p.handle, nil, nil, false, 0, 0, 0)
            p.server_vip = japi.DzAPI_Map_GetPlatformVIP(p.handle) > 0
            p.server_game_count = japi.RequestExtraIntegerData(45, p.handle, nil, nil, false, 0, 0, 0)
            -- 关闭 视距 显血显蓝 智能施法
            japi.RequestExtraBooleanData(43, p.handle, null, null, false, 1, 0, 0)
            japi.RequestExtraBooleanData(43, p.handle, null, null, false, 2, 0, 0)
            japi.RequestExtraBooleanData(43, p.handle, null, null, false, 3, 0, 0)
        end 
    end
end

return export
